
package com.huaweicloud.haydn.delivercore.agent.service.metadata.impl;

import static com.huaweicloud.haydn.delivercore.agent.config.Constants.DOT_FILETYPE_CSV;
import static com.huaweicloud.haydn.delivercore.agent.config.Constants.FILETYPE_PROPERTIES;
import static com.huaweicloud.haydn.delivercore.agent.config.Constants.FILETYPE_ZIP;
import static com.huaweicloud.haydn.delivercore.agent.config.Constants.SYS_URL;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.huaweicloud.haydn.delivercore.agent.common.exception.BusinessErrorEnum;
import com.huaweicloud.haydn.delivercore.agent.common.exception.BusinessException;
import com.huaweicloud.haydn.delivercore.agent.config.DatabaseContext;
import com.huaweicloud.haydn.delivercore.agent.dto.CommonResult;
import com.huaweicloud.haydn.delivercore.agent.dto.excel.DbModelExcelDto;
import com.huaweicloud.haydn.delivercore.agent.dto.haydn.DataMonitoringReportDto;
import com.huaweicloud.haydn.delivercore.agent.dto.haydn.DbMonitoringObjResultDto;
import com.huaweicloud.haydn.delivercore.agent.dto.haydn.ExcelParseDto;
import com.huaweicloud.haydn.delivercore.agent.service.CommonUtils;
import com.huaweicloud.haydn.delivercore.agent.service.HttpRequestService;
import com.huaweicloud.haydn.delivercore.agent.service.metadata.DatabaseUtil;
import com.huaweicloud.haydn.delivercore.agent.service.metadata.ImplementMonitoringService;
import com.huaweicloud.haydn.delivercore.agent.utils.HiveAuthUtil;
import com.huaweicloud.haydn.delivercore.agent.utils.SSLUtils;
import com.huaweicloud.haydn.delivercore.agent.utils.ZipUtil;

import lombok.extern.slf4j.Slf4j;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import javax.annotation.PostConstruct;

/**
 * 功能描述
 *
 * @since 2022-12-21
 */
@Service
@Slf4j
public class ImplementMonitoringServiceImpl implements ImplementMonitoringService {

    private static final String[] METADATA_TYPE =
        {"tablenaming", "tablefield", "consistencytablerows", "consistencytablefield", "consistencytablecontent"};

    private static final List<String> METADATA_TYPE_LIST = Arrays.asList(METADATA_TYPE);

    private static final String NUMBER_REGEXP = "^[0-9]{8}$";

    @PostConstruct
    public void postConstruct() {
        SSLUtils.disableSslVerification();
    }

    @Autowired
    private ZipUtil zipUtil;

    @Autowired
    private DatabaseContext databaseContext;

    @Autowired
    private HttpRequestService httpRequestService;

    @Autowired
    private CommonUtils commonUtils;

    @Override
    public void parseAndUpload(String accessCode, String projectId, String url) {
        ZipFile zip = null;
        try {
            zip = new ZipFile(new File(System.getProperty(SYS_URL), "monitorResult." + FILETYPE_ZIP),
                StandardCharsets.UTF_8);
            Enumeration<? extends ZipEntry> entries = zip.entries();
            DataMonitoringReportDto dataMonitoringReportDto = new DataMonitoringReportDto();
            while (entries.hasMoreElements()) {
                parseZip(zip, entries, dataMonitoringReportDto);
            }
            log.info("Successfully parsed the compressed package!");
            HttpHeaders headers = new HttpHeaders();
            headers.set("Content-Type", "application/json;charset=utf8");
            headers.set("access-code", accessCode);
            headers.set("deliver-project-id", projectId);
            HttpEntity<String> entity =
                new HttpEntity<>(new ObjectMapper().writeValueAsString(dataMonitoringReportDto), headers);
            ResponseEntity<CommonResult> resp =
                httpRequestService.execute(url, HttpMethod.POST, entity, CommonResult.class);
            if (resp.getBody() == null) {
                throw new BusinessException(BusinessErrorEnum.BASE_INTERNAL_SERVER_ERROR, "response is null!");
            }
        } catch (IOException | ParseException e) {
            log.error(e.getMessage());
        } finally {
            if (zip != null) {
                try {
                    zip.close();
                } catch (IOException e) {
                    log.error("Close zip failed!");
                    log.error(e.getMessage(), e);
                }
            }
        }
    }

    /**
     * 解析压缩包
     */
    private void parseZip(ZipFile zip, Enumeration<? extends ZipEntry> entries,
        DataMonitoringReportDto dataMonitoringReportDto) throws ParseException, IOException {
        ZipEntry zipEntry = entries.nextElement();
        String csvFullName = zipEntry.getName();
        String csvName = csvFullName.substring(0, csvFullName.lastIndexOf(".")).toLowerCase(Locale.US);
        csvNameCheck(csvName);
        String[] split = csvName.split("_");
        String idx = split[0];
        String typeName = split[1];
        String genDate = split[2];
        if (!"csv".equals(csvFullName.substring(csvFullName.lastIndexOf(".") + 1).toLowerCase(Locale.US))) {
            throw new BusinessException(BusinessErrorEnum.BASE_INTERNAL_SERVER_ERROR);
        }
        ExcelParseDto excelParseDto = new ExcelParseDto();
        excelParseDto.setName(csvFullName);
        excelParseDto.setGenDate(new SimpleDateFormat("yyyyMMdd").parse(genDate));
        excelParseDto.setStream(zip.getInputStream(zipEntry));
        try (InputStream inputStream =
            new FileInputStream(System.getProperty(SYS_URL) + File.separator + "application." + FILETYPE_PROPERTIES)) {
            Properties monitorConfig = new Properties();
            monitorConfig.load(inputStream);
            Map<String, List<DbMonitoringObjResultDto>> map = new HashMap<>();
            List<DbMonitoringObjResultDto> objResultDtoList = genDbDtoList(excelParseDto.getStream());
            if ("tablenaming".equals(typeName)) {
                String uuid = monitorConfig.getProperty("monitor.target.datamodel.tablenaming.uuid." + idx);
                if (StringUtils.isBlank(uuid)) {
                    return;
                }
                objResultDtoList
                    .forEach(dbMonitoringObjResultDto -> dbMonitoringObjResultDto.setMonitoringObjectUuid(uuid));
                map.put("1", objResultDtoList);
                dataMonitoringReportDto.setTableNamingMap(map);
            } else if ("tablefield".equals(typeName)) {
                String uuid = monitorConfig.getProperty("monitor.target.datamodel.tablefield.uuid." + idx);
                if (StringUtils.isBlank(uuid)) {
                    return;
                }
                objResultDtoList
                    .forEach(dbMonitoringObjResultDto -> dbMonitoringObjResultDto.setMonitoringObjectUuid(uuid));
                map.put("1", objResultDtoList);
                dataMonitoringReportDto.setAdditionalFieldMap(map);
            }
        } catch (IOException e) {
            log.error(e.getMessage());
        }
    }

    private List<DbMonitoringObjResultDto> genDbDtoList(InputStream stream) {
        List<DbMonitoringObjResultDto> resList = new ArrayList<>();
        EasyExcel.read(stream, DbModelExcelDto.class, new ReadListener<DbModelExcelDto>() {
            @Override
            public void invoke(DbModelExcelDto data, AnalysisContext analysisContext) {
                DbMonitoringObjResultDto dbDto = new DbMonitoringObjResultDto();
                BeanUtils.copyProperties(data, dbDto);
                resList.add(dbDto);
            }

            // 表头校验
            @Override
            public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            }
        }).excelType(ExcelTypeEnum.CSV).autoTrim(true).headRowNumber(1).sheet().doRead();
        return resList;
    }

    public void csvNameCheck(String csvName) {
        if (!csvName.contains("_")) {
            throw new BusinessException(BusinessErrorEnum.BASE_INTERNAL_SERVER_ERROR);
        }
        String[] split = csvName.split("_");
        if (split.length > 3 || !METADATA_TYPE_LIST.contains(split[1]) || !split[2].matches(NUMBER_REGEXP)) {
            throw new BusinessException(BusinessErrorEnum.BASE_INTERNAL_SERVER_ERROR);
        }
    }

    @Override
    public void genTableNamingData() {
        genDataType("tablenaming");
    }

    @Override
    public void genAdditionalFieldData() {
        genDataType("tablefield");
    }

    /**
     * 生成excel文件
     */
    public void genDataType(String type) {
        try (InputStream inputStream =
            new FileInputStream(System.getProperty(SYS_URL) + File.separator + "application." + FILETYPE_PROPERTIES)) {
            Properties monitorConfig = new Properties();
            monitorConfig.load(inputStream);
            for (int i = 0; i < 100; i++) {
                if (!read(monitorConfig, i + 1)) {
                    log.info("break at i = " + i + ", idx = " + i + 1);
                    break;
                }
                genDataInPool(i + 1, monitorConfig, type);
            }
        } catch (IOException e) {
            log.error(e.getMessage());
        }
    }

    private boolean read(Properties dataSourceConfig, int i) {
        String dbType = dataSourceConfig.getProperty("monitor.target.dbtype." + i);
        String hosts = dataSourceConfig.getProperty("monitor.target.hosts." + i);
        String port = dataSourceConfig.getProperty("monitor.target.port." + i);
        String userName = dataSourceConfig.getProperty("monitor.target.username." + i);
        String password = dataSourceConfig.getProperty("monitor.target.password." + i);
        boolean proBase =
            StringUtils.isNotEmpty(dbType) && StringUtils.isNotEmpty(hosts) && StringUtils.isNotEmpty(port);
        boolean proSuper = StringUtils.isNotEmpty(userName) && StringUtils.isNotEmpty(password);
        return proBase && proSuper;
    }

    private void genDataInPool(int idx, Properties dataSourceConfig, String type) {
        String dbType = dataSourceConfig.getProperty("monitor.target.dbtype." + idx);
        String hosts = dataSourceConfig.getProperty("monitor.target.hosts." + idx);
        String port = dataSourceConfig.getProperty("monitor.target.port." + idx);
        String userName = dataSourceConfig.getProperty("monitor.target.username." + idx);
        String password = dataSourceConfig.getProperty("monitor.target.password." + idx);
        DatabaseUtil dbUtil = databaseContext.getStrategy(dbType);
        String databaseName = dataSourceConfig.getProperty("monitor.target.database." + idx);
        String isSafeMode = dataSourceConfig.getProperty("monitor.target.safemode." + idx);

        if ("MRS-Hudi".equals(dbType) && "true".equals(isSafeMode)) {
            databaseName = HiveAuthUtil.getHiveAuthJDBC(userName, databaseName);
        }

        dbUtil.init(hosts, port, databaseName, userName, password, dbType, "", "");
        String schemaSelected = "";
        String tableSelected = "";
        String uuid = "";
        if ("tablenaming".equals(type)) {
            schemaSelected =
                Optional.ofNullable(dataSourceConfig.getProperty("monitor.target.datamodel.tablenaming.schema." + idx))
                    .orElse("");
            tableSelected =
                Optional.ofNullable(dataSourceConfig.getProperty("monitor.target.datamodel.tablenaming.table." + idx))
                    .orElse("");
            uuid = Optional.ofNullable(dataSourceConfig.getProperty("monitor.target.datamodel.tablenaming.uuid." + idx))
                .orElse("");
        } else if ("tablefield".equals(type)) {
            schemaSelected =
                Optional.ofNullable(dataSourceConfig.getProperty("monitor.target.datamodel.tablefield.schema." + idx))
                    .orElse("");
            tableSelected =
                Optional.ofNullable(dataSourceConfig.getProperty("monitor.target.datamodel.tablefield.table." + idx))
                    .orElse("");
            uuid = Optional.ofNullable(dataSourceConfig.getProperty("monitor.target.datamodel.tablefield.uuid." + idx))
                .orElse("");
        }
        log.info("Successfully read the configuration file and successfully initialized!");
        Connection conn = null;
        try {
            conn = dbUtil.getConnection();
            if ("dws".equals(dbType)) {
                genDwsExcelDto(dbUtil, databaseName, schemaSelected, tableSelected, idx + "", type, conn, uuid);
            } else {
                genHudiExcelDto(dbUtil, databaseName, schemaSelected, tableSelected, idx + "", type, conn, uuid);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BusinessException(BusinessErrorEnum.BASE_INTERNAL_SERVER_ERROR, "Failed to generate excel!");
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    log.error("close connection failed!", e);
                }
            }
        }
    }

    public void genHudiExcelDto(DatabaseUtil dbUtil, String dbNames, String schemaNames, String tableNames, String idx,
        String type, Connection conn, String uuid) {
        List<String> tables;
        if (StringUtils.isNotBlank(tableNames)) {
            tables = Arrays.asList(tableNames.split(","));
        } else {
            tables = getAllTables(dbUtil, conn);
        }
        List<DbModelExcelDto> dbModelExcelDtos = getAllFields(dbNames, schemaNames, tables, type, conn);
        dbModelExcelDtos.forEach(dto -> dto.setMonitoringObjectUuid(uuid));
        String fileName =
            idx + "_" + type + "_" + new SimpleDateFormat("yyyyMMdd").format(new Date()) + DOT_FILETYPE_CSV;
        ExcelWriter excelWriter = EasyExcel.write(fileName, DbModelExcelDto.class).build();
        excelWriter.write(new HashSet<>(dbModelExcelDtos), EasyExcel.writerSheet("sheet").build());
        excelWriter.finish();
        zipUtil.execZip(fileName, type, "monitorResult");
        log.info("File {} compressed successfully!", fileName);
    }

    public List<String> getAllTables(DatabaseUtil dbUtil, Connection conn) {
        List<String> tables = new ArrayList<>();
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            String sql = dbUtil.getAllTablesSql();
            ps = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            rs = ps.executeQuery();
            while (rs.next()) {
                tables.add(rs.getString(1));
            }
            return tables;
        } catch (SQLException e) {
            throw new BusinessException(BusinessErrorEnum.BASE_INTERNAL_SERVER_ERROR);
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (ps != null) {
                    ps.close();
                }
            } catch (SQLException e) {
                log.error("close db failed: ", e);
            }
        }
    }

    public List<DbModelExcelDto> getAllFields(String dbNames, String schemas, List<String> tables, String type,
        Connection conn) {
        List<DbModelExcelDto> dbModelExcelDtos = new ArrayList<>();
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            if (StringUtils.isNotBlank(dbNames) && dbNames.split(";").length > 1) {
                dbNames = dbNames.split(";")[0];
            }
            for (String table : tables) {
                if ("all".equals(table)) {
                    continue;
                }
                String sql = String.format("desc %s.%s", dbNames, table);
                ps = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
                rs = ps.executeQuery();
                List<String> fileds = new ArrayList<>();
                while (rs.next()) {
                    fileds.add(rs.getString(1));
                }
                fileds.removeAll(Arrays.asList("_hoodie_commit_seqno", "_hoodie_file_name", "_hoodie_partition_path",
                    "_hoodie_record_key", "_hoodie_commit_time"));
                if ("tablenaming".equals(type)) {
                    DbModelExcelDto dbModelExcelDto = new DbModelExcelDto();
                    dbModelExcelDto.setTargetDbName(dbNames);
                    dbModelExcelDto.setTargetSchemaName(schemas);
                    dbModelExcelDto.setTargetTableName(table);
                    dbModelExcelDto.setTargetFieldName(String.join("&", fileds));
                    dbModelExcelDtos.add(dbModelExcelDto);
                } else if ("tablefield".equals(type)) {
                    String finalDbNames = dbNames;
                    fileds.forEach(filed -> {
                        DbModelExcelDto dbModelExcelDto = new DbModelExcelDto();
                        dbModelExcelDto.setTargetDbName(finalDbNames);
                        dbModelExcelDto.setTargetSchemaName(schemas);
                        dbModelExcelDto.setTargetTableName(table);
                        dbModelExcelDto.setTargetFieldName(filed);
                        dbModelExcelDtos.add(dbModelExcelDto);
                    });
                }
            }
            return dbModelExcelDtos;
        } catch (SQLException e) {
            log.error(e.getMessage(), e);
            throw new BusinessException(BusinessErrorEnum.BASE_INTERNAL_SERVER_ERROR);
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (ps != null) {
                    ps.close();
                }
            } catch (SQLException e) {
                log.error("close db failed: ", e);
            }
        }
    }

    public List<String> getDwsAllSchemas(DatabaseUtil dbUtil, Connection conn) {
        List<String> schemas = new ArrayList<>();
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            String sql = dbUtil.getAllSchemasSql();
            ps = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            rs = ps.executeQuery();
            while (rs.next()) {
                schemas.add(rs.getString(1));
            }
            return schemas;
        } catch (SQLException e) {
            throw new BusinessException(BusinessErrorEnum.BASE_INTERNAL_SERVER_ERROR);
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (ps != null) {
                    ps.close();
                }
            } catch (SQLException e) {
                log.error("close db failed: ", e);
            }
        }
    }

    public List<String> getDwsAllTables(DatabaseUtil dbUtil, Connection conn, String schemaNames) {
        List<String> schemas;
        if (StringUtils.isNotBlank(schemaNames)) {
            schemas = Arrays.asList(schemaNames.split(","));
        } else {
            schemas = getDwsAllSchemas(dbUtil, conn);
        }
        if (CollectionUtils.isEmpty(schemas)) {
            return new ArrayList<>();
        }
        List<String> tables = new ArrayList<>();
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            String schemaStr = String.join(",", schemas);
            String sql = dbUtil.getAllTablesByDbSql(commonUtils.sqlQueryBuild(schemaStr));
            ps = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            rs = ps.executeQuery();
            while (rs.next()) {
                tables.add(rs.getString(1) + "." + rs.getString(2));
            }
            return tables;
        } catch (SQLException e) {
            throw new BusinessException(BusinessErrorEnum.BASE_INTERNAL_SERVER_ERROR);
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (ps != null) {
                    ps.close();
                }
            } catch (SQLException e) {
                log.error("close db failed: ", e);
            }
        }
    }

    public void genDwsExcelDto(DatabaseUtil dbUtil, String dbNames, String schemaNames, String tableNames, String idx,
        String type, Connection conn, String uuid) {
        List<String> tables = getDwsAllTables(dbUtil, conn, schemaNames);
        if (StringUtils.isNotBlank(tableNames)) {
            List<String> tableNms = Arrays.asList(tableNames.split(","));
            tables = tables.stream()
                .filter(item -> tableNms.stream().allMatch(each -> item.contains(each)))
                .collect(Collectors.toList());
        }
        List<DbModelExcelDto> dbModelExcelDtos = getDwsAllFields(dbUtil, dbNames, schemaNames, tables, type, conn);
        dbModelExcelDtos.stream().forEach(dto -> dto.setMonitoringObjectUuid(uuid));
        HashSet<DbModelExcelDto> fieldExcelDtos = new HashSet<>(dbModelExcelDtos);
        String fileName =
            idx + "_" + type + "_" + new SimpleDateFormat("yyyyMMdd").format(new Date()) + DOT_FILETYPE_CSV;
        ExcelWriter excelWriter = EasyExcel.write(fileName, DbModelExcelDto.class).build();
        WriteSheet writeSheet = EasyExcel.writerSheet("sheet").build();
        excelWriter.write(fieldExcelDtos, writeSheet);
        excelWriter.finish();
        String zipName = "monitorResult";
        zipUtil.execZip(fileName, type, zipName);
        log.info("File {} compressed successfully!", fileName);
    }

    public List<DbModelExcelDto> getDwsAllFields(DatabaseUtil dbUtil, String dbNames, String schemas,
        List<String> tables, String type, Connection conn) {
        List<DbModelExcelDto> dbModelExcelDtos = new ArrayList<>();
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            if (StringUtils.isNotBlank(dbNames) && dbNames.split(";").length > 1) {
                dbNames = dbNames.split(";")[0];
            }
            for (String table : tables) {
                String[] tableArr = table.split("\\.");
                String schema = tableArr[0];
                String tableNm = tableArr[1];
                String sql = dbUtil.getAllFieldsSql();
                ps = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
                ps.setString(1, table);
                rs = ps.executeQuery();
                List<String> fileds = new ArrayList<>();
                while (rs.next()) {
                    dwsField(fileds, rs.getString(1));
                }
                if ("tablenaming".equals(type)) {
                    DbModelExcelDto dbModelExcelDto = new DbModelExcelDto();
                    dbModelExcelDto.setTargetDbName(dbNames);
                    dbModelExcelDto.setTargetSchemaName(schema);
                    dbModelExcelDto.setTargetTableName(tableNm);
                    dbModelExcelDto.setTargetFieldName(String.join("&", fileds));
                    dbModelExcelDtos.add(dbModelExcelDto);
                } else if ("tablefield".equals(type)) {
                    String finalDbNames = dbNames;
                    fileds.forEach(filed -> {
                        DbModelExcelDto dbModelExcelDto = new DbModelExcelDto();
                        dbModelExcelDto.setTargetDbName(finalDbNames);
                        dbModelExcelDto.setTargetSchemaName(schema);
                        dbModelExcelDto.setTargetTableName(tableNm);
                        dbModelExcelDto.setTargetFieldName(filed);
                        dbModelExcelDtos.add(dbModelExcelDto);
                    });
                }
            }
            return dbModelExcelDtos;
        } catch (SQLException e) {
            log.error(e.getMessage(), e);
            throw new BusinessException(BusinessErrorEnum.BASE_INTERNAL_SERVER_ERROR);
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (ps != null) {
                    ps.close();
                }
            } catch (SQLException e) {
                log.error("close db failed: ", e);
            }
        }
    }

    public void dwsField(List<String> fileds, String rs) {
        String[] arr = rs.split("\n\t");
        for (int i = 0; i < arr.length; i++) {
            if (i == 0) {
                continue;
            }
            String filed = arr[i].split(" ")[0];
            fileds.add(filed);
        }
    }
}
